package com.example.everying.service.content.impl;

import cn.hutool.core.util.ObjectUtil;
import com.aliyun.oss.ServiceException;
import com.aliyuncs.utils.StringUtils;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.everying.constant.ChatMessageConstant;
import com.example.everying.context.UserContext;
import com.example.everying.framework.websocket.service.WebSocketChatService;
import com.example.everying.mapper.content.ActivityCommentMapper;
import com.example.everying.model.entity.chat.ChatMessagesEntity;
import com.example.everying.model.entity.content.ActivityArticle;
import com.example.everying.model.entity.content.ActivityComment;
import com.example.everying.model.entity.user.UserEntity;
import com.example.everying.model.vo.content.ActivityCommentVo;
import com.example.everying.model.vo.user.UserInfoVo;
import com.example.everying.service.chat.ChatConversationService;
import com.example.everying.service.chat.ChatMessagesService;
import com.example.everying.service.chat.impl.RedDotService;
import com.example.everying.service.content.ActivityArticleService;
import com.example.everying.service.content.ActivityCommentService;
import com.example.everying.service.user.UserService;
import com.example.everying.utils.*;
import com.github.houbb.sensitive.word.exception.SensitiveWordException;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * @program: everything
 * @description: 评论实现层
 * @author: zw
 * @create: 2025-05-19 10:14
 **/
@Service
@Slf4j
public class ActivityCommentServiceImpl extends ServiceImpl<ActivityCommentMapper, ActivityComment> implements ActivityCommentService {

    private static final String ARTICLE_COMMENTS_KEY = "article:%s:comments";
    private static final String COMMENT_REPLIES_KEY = "comment:%s:replies";
    private static final String COMMENT_DATA_KEY = "comment:%s";
    private static final String PENDING_SYNC_KEY = "pending_sync_comments";
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Autowired
    private ChatConversationService chatConversationService;

    @Autowired
    private ActivityArticleService activityArticleService;
    @Autowired
    private ChatMessagesService chatMessagesService;

    @Autowired
    private SensitiveWordReplaceUtils sensitiveWordReplaceUtils;
    @Autowired
    private UserService userService;
    @Autowired
    private QueryLocationUtil queryLocationUtil;
    @Autowired
    private AliGreenModerationUtil textModerationUtil;
    @Autowired
    private RedDotService redDotService;


    @Override
    public IPage<ActivityComment> selectPage(Page<ActivityComment> pageParam, ActivityCommentVo comment) {
        QueryWrapper<ActivityComment> wrapper = new QueryWrapper<>();
        wrapper.like(ObjectUtil.isNotEmpty(comment.getContent()), "content", comment.getContent());
        //调用mapper的方法
        Page<ActivityComment> commentPage = baseMapper.selectPage(pageParam, wrapper);
        commentPage.getRecords().stream().forEach(item -> {
            //设置其他参数
//            this.setOtherParam(item);
        });
        return commentPage;
    }

    /**
     * 添加评论
     *
     * @param comment
     */
    @Override
    public void addComment(ActivityComment comment) {

        UserEntity user = UserContext.getUser();
        comment.setId(RandomUtil.generateId());
        comment.setUserId(user.getId());
        comment.setCreateTime(LocalDateTime.now());
        String parentId = comment.getParentId();
        //上级id无
        if (ObjectUtil.isEmpty(parentId)) {
            comment.setParentId(String.valueOf(0));
            this.save(comment);
        } else {
            this.queryComment(parentId);
            this.save(comment);
        }
    }

    /**
     * 根据父id查询id是否存在
     *
     * @param id
     * @return
     */
    private ActivityComment queryComment(String id) {
        ActivityComment comment = baseMapper.selectById(id);
        if (ObjectUtil.isEmpty(comment)) {
            throw new CampusException("id不存在", 201);
        }
        return comment;
    }

    @Override
    @Transactional
    public ActivityComment saveComment(ActivityComment comment, HttpServletRequest request) {
        // 添加内容长度检查
        if (comment.getContent() != null && comment.getContent().length() > 500) {
            throw new CampusException("评论内容不能超过500个字符", 201);
        }
        if (comment.getContent() != null && !comment.getContent().isEmpty()) {
            //敏感词替换标题和内容
            boolean hasSensitiveContent = textModerationUtil.containsProhibitedWords(comment.getContent());
            // 如果存在敏感词，抛出异常或返回失败
            if (hasSensitiveContent) {
                // 抛出自定义异常，携带错误提示
                throw new SensitiveWordException("评论包含敏感内容，请检查后再提交");
            }
        }
        UserInfoVo user = UserContext.getUser();
        // 更新用户地址
        String location = queryLocationUtil.queryLocation(IpUtils.getClientIp(request));
        user.setLocation(location);
        userService.updateById(user);
        UserContext.setUser(user);
        comment.setLocation(location);
        comment.setId(RandomUtil.generateId());
        comment.setCreateTime(LocalDateTime.now());
        comment.setUserId(user.getId());
        comment.setContent(comment.getContent());
        comment.setComPictureUrl(comment.getComPictureUrl());
//        comment.setContent(sensitiveWordReplaceUtils.replaceSensitiveWords(comment.getContent()));

        // 参数验证
        if (comment == null) {
            throw new IllegalArgumentException("评论对象不能为空");
        }
        if (StringUtils.isEmpty(comment.getArticleId())) {
            throw new IllegalArgumentException("文章ID不能为空");
        }
        try {
            // 保存到Redis
            saveToRedis(comment, String.format(ARTICLE_COMMENTS_KEY, comment.getArticleId()));
            // 添加到待同步队列
            redisTemplate.opsForSet().add(PENDING_SYNC_KEY, comment.getId());
        } catch (Exception e) {
            log.error("插入评论失败: {}", comment, e);
            throw new ServiceException("评论保存失败", e);
        }
        // 保存到Redis
//        saveToRedis(comment, String.format(ARTICLE_COMMENTS_KEY, comment.getArticleId()));
//        // 添加到待同步队列
//        redisTemplate.opsForSet().add(PENDING_SYNC_KEY, comment.getId());

        saveMessage(comment);
        return comment;
    }

    /**
     * 创建回复
     *
     * @param commentId
     * @param reply
     * @return
     */
    @Override
    @Transactional
    public ActivityComment saveReply(String commentId, ActivityComment reply) {
        reply.setId(RandomUtil.generateId());
        reply.setParentId(commentId);
        reply.setCreateTime(LocalDateTime.now());
        // 保存到Redis
        saveToRedis(reply, String.format(COMMENT_REPLIES_KEY, commentId));
        // 添加到待同步队列
        redisTemplate.opsForSet().add(PENDING_SYNC_KEY, reply.getId());
        return reply;
    }

    @Override
    public List<ActivityComment> getCommentsByArticle(String articleId) {
        String key = String.format(ARTICLE_COMMENTS_KEY, articleId);
        return getCommentsFromRedis(key);
    }

    @Override
    public List<ActivityComment> getRepliesByComment(String commentId) {
        String key = String.format(COMMENT_REPLIES_KEY, commentId);
        return getCommentsFromRedis(key);
    }


    private void saveToRedis(ActivityComment comment, String listKey) {
        String dataKey = String.format(COMMENT_DATA_KEY, comment.getId());
        // 保存评论数据
        redisTemplate.opsForValue().set(dataKey, comment);
        // 添加到有序集合(使用 comment.getId() 作为成员，时间戳作为分数)
        redisTemplate.opsForZSet().add(listKey, comment.getId(),
                comment.getCreateTime().toEpochSecond(ZoneOffset.UTC));
        // 设置过期时间(24小时)
        redisTemplate.expire(dataKey, 24, TimeUnit.HOURS);
        redisTemplate.expire(listKey, 24, TimeUnit.HOURS);
    }

    private List<ActivityComment> getCommentsFromRedis(String listKey) {
        List<ActivityComment> comments = new ArrayList<>();
        // 获取有序集合中的所有评论ID（按时间排序）
        Set<Object> commentIds = redisTemplate.opsForZSet().range(listKey, 0, -1);
        if (commentIds != null) {
            for (Object commentId : commentIds) {
                String dataKey = String.format(COMMENT_DATA_KEY, commentId);
                ActivityComment comment = (ActivityComment) redisTemplate.opsForValue().get(dataKey);
                if (comment != null) {
                    comments.add(comment);
                }
            }
        }
        return comments;
    }

    @Override
    public List<ActivityCommentVo> getCommentsByArticleId(String articleId) {
        // 从数据库查询该文章的所有评论
        List<ActivityCommentVo> comments = baseMapper.commentList(articleId);

        if (comments.isEmpty()) {
            return new ArrayList<>();
        }
        // 用于存储所有评论的Map，key为评论ID
        Map<String, ActivityCommentVo> commentMap = new HashMap<>(comments.size());
        // 初始化所有评论的children列表
        for (ActivityCommentVo comment : comments) {
            comment.setChildren(new ArrayList<>());
            commentMap.put(comment.getId(), comment);
        }
        // 构建评论树结构
        return buildCommentTree(commentMap);
    }

    @Override
    @Transactional
    public void deleteCommentWithRelations(String commentId) {
        //获取所有子评论ID
        List<String> allCommentIds = new ArrayList<>();
        allCommentIds.add(commentId);
        findAllChildCommentIds(commentId, allCommentIds);
        //批量删除评论
        baseMapper.deleteIds(allCommentIds);
        // 修改互动消息表删除标志位
        if (commentId != null){
            chatMessagesService.updateDeleteFlag(commentId);
        }

        // TODO 更新文章评论计数
        ActivityComment comment = getById(commentId);
        if (comment != null) {
//            articleService.decrementCommentCount(comment.getArticleId(), allCommentIds.size());
        }
    }

    /**
     * @param userId
     * @return
     */
    @Override
    public ActivityComment getLastCommentHaveParent(String userId) {
        return baseMapper.getLastCommentHaveParent(userId);
    }

    /**
     * @param parentId
     * @return
     */
    @Override
    public ActivityComment getLastCommentHaveArticle(String parentId) {
        return baseMapper.getLastCommentHaveArticle(parentId);
    }

    private void findAllChildCommentIds(String parentId, List<String> allIds) {
        List<ActivityComment> children = baseMapper.selectList(
                new QueryWrapper<ActivityComment>().eq("parent_id", parentId)
        );
        for (ActivityComment child : children) {
            allIds.add(child.getId());
            findAllChildCommentIds(child.getId(), allIds);
        }
    }

    // 构建评论树结构
    private List<ActivityCommentVo> buildCommentTree(Map<String, ActivityCommentVo> commentMap) {
        List<ActivityCommentVo> rootComments = new ArrayList<>();
        Map<String, List<ActivityCommentVo>> childrenMap = new HashMap<>();

        // 第一次遍历：按父ID分组所有子评论
        for (ActivityCommentVo comment : commentMap.values()) {
            String parentId = comment.getParentId();
            if (parentId == null || parentId.isEmpty()) {
                rootComments.add(comment);
            } else {
                childrenMap.computeIfAbsent(parentId, k -> new ArrayList<>()).add(comment);
            }
        }

        // 第二次遍历：将子评论添加到父评论中
        for (Map.Entry<String, List<ActivityCommentVo>> entry : childrenMap.entrySet()) {
            String parentId = entry.getKey();
            List<ActivityCommentVo> children = entry.getValue();

            ActivityComment parentComment = findParentComment(parentId, commentMap);
            if (parentComment != null) {
                parentComment.getChildren().addAll(children);
                parentComment.setHasChildren(true);
            } else {
                // 父评论不存在，将子评论作为根评论处理
                rootComments.addAll(children);
            }
        }

        // 递归排序
        sortCommentsRecursively(rootComments);
        return rootComments;
    }


    // 查找父评论的方法
    private ActivityCommentVo findParentComment(String parentId, Map<String, ActivityCommentVo> commentMap) {
        // 1. 直接查找
        ActivityCommentVo parentComment = commentMap.get(parentId);
        if (parentComment != null) {
            return parentComment;
        }

        // 2. 尝试处理ID格式后再次查找
        if (parentId != null) {
            // 尝试去除尾部'0'
            if (parentId.endsWith("0")) {
                String potentialParentId = parentId.substring(0, parentId.length() - 1);
                parentComment = commentMap.get(potentialParentId);
                if (parentComment != null) {
                    return parentComment;
                }
            }

            // 3. 尝试遍历匹配（确保键和parentId都清理空格）
            String cleanParentId = parentId.trim();
            for (String key : commentMap.keySet()) {
                String cleanKey = key != null ? key.trim() : "";
                if (!cleanKey.isEmpty() && cleanKey.equals(cleanParentId)) {
                    return commentMap.get(key);
                }
            }
        }

        return null;
    }

    // 递归对评论进行时间排序
    private void sortCommentsRecursively(List<ActivityCommentVo> comments) {
        if (comments == null || comments.isEmpty()) {
            return;
        }
        // 对当前层级的评论进行排序
        comments.sort((c1, c2) -> c2.getCreateTime().compareTo(c1.getCreateTime()));

        // 递归对子评论进行排序
        for (ActivityCommentVo comment : comments) {
            if (comment.getChildren() != null && !comment.getChildren().isEmpty()) {
                sortCommentsRecursively(comment.getChildren());
            }
        }
    }

//    public List<ActivityComment> getCommentsByArticleId(String articleId) {
//        // 构造文章评论的key
//        String listKey = String.format(ARTICLE_COMMENTS_KEY, articleId);
//
//        // 1. 使用Redis缓存优先策略
//        Set<Object> redisCommentIds = redisTemplate.opsForZSet().reverseRange(listKey, 0, -1);
//        Map<String, ActivityComment> commentMap = new HashMap<>();
//        boolean needDbQuery = false;
//
//        // 2. 批量检查Redis中的评论数据是否完整
//        if (redisCommentIds != null && !redisCommentIds.isEmpty()) {
//            List<String> dataKeys = new ArrayList<>(redisCommentIds.size());
//            Map<String, String> idToKeyMap = new HashMap<>();
//
//            // 批量构造数据键并建立ID到键的映射
//            for (Object commentIdObj : redisCommentIds) {
//                String commentId = commentIdObj.toString();
//                String dataKey = String.format(COMMENT_DATA_KEY, commentId);
//                dataKeys.add(dataKey);
//                idToKeyMap.put(commentId, dataKey);
//            }
//
//            // 批量检查键是否存在
//            List<Object> keyExistResults = redisTemplate.executePipelined((RedisCallback<Object>) connection -> {
//                for (String dataKey : dataKeys) {
//                    connection.exists(dataKey.getBytes());
//                }
//                return null;
//            });
//
//            // 批量获取存在的键的值
//            List<String> existingKeys = new ArrayList<>();
//            for (int i = 0; i < dataKeys.size(); i++) {
//                if (Boolean.TRUE.equals(keyExistResults.get(i))) {
//                    existingKeys.add(dataKeys.get(i));
//                } else {
//                    needDbQuery = true; // 有缺失的评论，需要查询数据库
//                }
//            }
//
//            // 批量获取评论数据
//            if (!existingKeys.isEmpty()) {
//                List<Object> commentList = redisTemplate.executePipelined((RedisCallback<Object>) connection -> {
//                    for (String dataKey : existingKeys) {
//                        connection.get(dataKey.getBytes());
//                    }
//                    return null;
//                });
//
//                // 处理获取的评论数据
//                int index = 0;
//                for (String dataKey : existingKeys) {
//                    ActivityComment comment = (ActivityComment) commentList.get(index++);
//                    if (comment != null) {
//                        commentMap.put(comment.getId(), comment);
//                    }
//                }
//            }
//        } else {
//            needDbQuery = true;
//        }
//
//        // 3. 如果需要，从数据库查询缺失的评论
//        if (needDbQuery) {
//            List<String> dbCommentIds = baseMapper.selectCommentIdsByArticleId(articleId);
//            if (!dbCommentIds.isEmpty()) {
//                // 只查询Redis中不存在的评论
//                List<String> missingCommentIds = dbCommentIds.stream()
//                        .filter(id -> !commentMap.containsKey(id))
//                        .collect(Collectors.toList());
//
//                if (!missingCommentIds.isEmpty()) {
//                    List<ActivityComment> dbComments = baseMapper.selectCommentsByIds(missingCommentIds);
//                    // 异步更新Redis
//                    asyncUpdateRedisComments(dbComments);
//
//                    // 添加到评论映射
//                    for (ActivityComment comment : dbComments) {
//                        commentMap.put(comment.getId(), comment);
//                    }
//                }
//            }
//        }
//
//        // 4. 构建评论树结构（使用更高效的方法）
//        return buildCommentTree(commentMap);
//    }
    // 构建评论树结构
//    private List<ActivityComment> buildCommentTree(Map<String, ActivityComment> commentMap) {
//        List<ActivityComment> rootComments = new ArrayList<>();
//        Map<String, List<ActivityComment>> childrenMap = new HashMap<>();
//
//        // 第一次遍历：按父ID分组所有子评论
//        for (ActivityComment comment : commentMap.values()) {
//            // 初始化children列表
//            comment.setChildren(new ArrayList<>());
//
//            String parentId = comment.getParentId();
//            if (parentId == null || parentId.isEmpty()) {
//                rootComments.add(comment);
//            } else {
//                // 将子评论按父ID分组
//                childrenMap.computeIfAbsent(parentId, k -> new ArrayList<>()).add(comment);
//            }
//        }
//
//        // 第二次遍历：将子评论添加到父评论中
//        for (Map.Entry<String, List<ActivityComment>> entry : childrenMap.entrySet()) {
//            String parentId = entry.getKey();
//            List<ActivityComment> children = entry.getValue();
//
//            // 尝试多种方式查找父评论
//            ActivityComment parentComment = findParentComment(parentId, commentMap);
//
//            if (parentComment != null) {
//                // 添加所有子评论并设置hasChildren标志
//                parentComment.getChildren().addAll(children);
//                parentComment.setHasChildren(true);
//            } else {
//                // 父评论不存在，将子评论作为根评论处理
//                rootComments.addAll(children);
//            }
//        }
//
//        // 递归排序
//        sortCommentsRecursively(rootComments);
//        return rootComments;
//    }
//    @Override
//    public List<ActivityComment> getCommentsByArticleId(String articleId) {
//        // 构造文章评论的key
//        String listKey = String.format(ARTICLE_COMMENTS_KEY, articleId);
//        // 从Redis中获取评论ID列表（按时间排序，从新到旧）
//        Set<Object> commentIds = redisTemplate.opsForZSet().reverseRange(listKey, 0, -1);
//        if (commentIds == null || commentIds.isEmpty()) {
//            return new ArrayList<>();
//        }
//        // 用于存储所有评论的Map，key为评论ID
//        Map<String, ActivityComment> commentMap = new HashMap<>();
//        // 存储根评论列表
//        List<ActivityComment> rootComments = new ArrayList<>();
//        // 第一次遍历：获取所有评论数据并存入Map
//        for (Object commentId : commentIds) {
//            String dataKey = String.format(COMMENT_DATA_KEY, commentId);
//            ActivityComment comment = (ActivityComment) redisTemplate.opsForValue().get(dataKey);
//            if (comment != null) {
//                comment.setChildren(new ArrayList<>());
//                commentMap.put(comment.getId(), comment);
//            }
//        }
//        // 构建评论树（支持多级嵌套）
//        for (ActivityComment comment : new ArrayList<>(commentMap.values())) {
//            String parentId = comment.getParentId();
//            if (parentId == null || parentId.isEmpty()) {
//                // 这是根评论
//                rootComments.add(comment);
//            } else {
//                // 这是子评论，递归查找其父评论
//                addToParentComment(comment, parentId, commentMap);
//            }
//        }
//        // 递归对所有层级的评论进行时间排序
//        sortCommentsRecursively(rootComments);
//        return rootComments;
//    }

    /**
     // 递归添加评论到父评论中
     private void addToParentComment(ActivityComment comment, String parentId, Map<String, ActivityComment> commentMap) {
     ActivityComment parentComment;
     parentComment = commentMap.get(parentId);
     System.out.println("parentComment: " + commentMap.get(parentId));
     System.out.println("获取到的父评论: " + parentComment);
     System.out.println("CommentMap keys: " + commentMap.keySet());
     // 方法2：如果直接获取失败，尝试处理ID格式后再次获取
     if (parentComment == null && parentId != null && parentId.endsWith("0")) {
     String potentialParentId = parentId.substring(0, parentId.length() - 1);
     System.out.println("尝试去除尾部'0'查找父评论，潜在ID: " + potentialParentId);
     parentComment = commentMap.get(potentialParentId);
     }
     // 方法3：如果还是失败，尝试遍历匹配（确保键和parentId都清理空格）
     //        if (parentComment == null) {
     //            String cleanParentId = parentId != null ? parentId.trim() : "";
     //            for (String key : commentMap.keySet()) {
     //                String cleanKey = key != null ? key.trim() : "";
     //                if (!cleanKey.isEmpty() && cleanKey.equals(cleanParentId)) {
     //                    parentComment = commentMap.get(key);
     //                    System.out.println("通过遍历找到匹配的父评论，键: " + key);
     //                    break;
     //                }
     //            }
     //        }
     if (parentComment != null) {
     // 初始化父评论的children列表（如果需要）
     if (parentComment.getChildren() == null) {
     parentComment.setChildren(new ArrayList<>());
     }
     // 将当前评论添加到父评论的children中
     parentComment.getChildren().add(comment);
     // 更新父评论的hasChildren状态
     parentComment.setHasChildren(true);
     }
     }

     // 递归对评论进行时间排序
     private void sortCommentsRecursively(List<ActivityComment> comments) {
     if (comments == null || comments.isEmpty()) {
     return;
     }
     // 对当前层级的评论进行排序
     comments.sort((c1, c2) -> c2.getCreateTime().compareTo(c1.getCreateTime()));
     // 递归对子评论进行排序
     for (ActivityComment comment : comments) {
     if (comment.getChildren() != null && !comment.getChildren().isEmpty()) {
     sortCommentsRecursively(comment.getChildren());
     }
     }
     }

     //生成评论的id
     private String generateUniqueId() {
     return RandomUtil.generateId();
     }
     @Override public List<ActivityComment> getCommentsByArticleId(String articleId) {
     // 构造文章评论的key
     String listKey = String.format(ARTICLE_COMMENTS_KEY, articleId);
     List<ActivityComment> comments = new ArrayList<>();
     // 1. 首先尝试从Redis获取数据
     Set<Object> redisCommentIds = redisTemplate.opsForZSet().reverseRange(listKey, 0, -1);
     Map<String, ActivityComment> commentMap = new HashMap<>();
     boolean needDbQuery = false;
     // 2. 检查Redis数据是否完整
     if (redisCommentIds != null && !redisCommentIds.isEmpty()) {
     for (Object commentId : redisCommentIds) {
     String dataKey = String.format(COMMENT_DATA_KEY, commentId.toString());
     ActivityComment comment = (ActivityComment) redisTemplate.opsForValue().get(dataKey);
     if (comment != null) {
     comment.setChildren(new ArrayList<>());
     commentMap.put(comment.getId(), comment);
     } else {
     // 如果有任何评论数据缺失，标记需要查询数据库
     needDbQuery = true;
     break;
     }
     }
     } else {
     // Redis中没有数据，需要查询数据库
     needDbQuery = true;
     }
     // 3. 如果需要，从数据库查询数据
     if (needDbQuery) {
     // 从数据库查询该文章的所有评论
     List<ActivityComment> dbComments = baseMapper.selectList(new QueryWrapper<ActivityComment>()
     .eq("article_id", articleId)
     .orderByDesc("create_time"));
     // 更新Redis缓存
     if (!dbComments.isEmpty()) {
     // 清除旧的Redis数据
     redisTemplate.delete(listKey);
     // 批量更新Redis
     updateRedisComments(dbComments);
     // 重新构建评论Map
     commentMap.clear();
     for (ActivityComment comment : dbComments) {
     comment.setChildren(new ArrayList<>());
     commentMap.put(comment.getId(), comment);
     }
     }
     }
     // 4. 构建评论树结构
     List<ActivityComment> rootComments = buildCommentTree(commentMap);
     return rootComments;
     }
     // 更新Redis缓存
     private void updateRedisComments(List<ActivityComment> comments) {
     if (comments == null || comments.isEmpty()) {
     return;
     }
     // 使用管道批量操作提高性能
     redisTemplate.executePipelined((RedisCallback<Object>) connection -> {
     for (ActivityComment comment : comments) {
     // 1. 存储评论详情
     String dataKey = String.format(COMMENT_DATA_KEY, comment.getId());
     redisTemplate.opsForValue().set(dataKey, comment, 24, TimeUnit.HOURS); // 设置24小时过期

     // 2. 更新文章评论列表
     String listKey = String.format(ARTICLE_COMMENTS_KEY, comment.getArticleId());
     redisTemplate.opsForZSet().add(listKey, comment.getId(),
     comment.getCreateTime().toEpochSecond(ZoneOffset.UTC));
     }
     return null;
     });
     }
     // 构建评论树结构
     private List<ActivityComment> buildCommentTree(Map<String, ActivityComment> commentMap) {
     List<ActivityComment> rootComments = new ArrayList<>();
     Map<String, List<ActivityComment>> childrenMap = new HashMap<>();
     // 第一次遍历：按父ID分组所有子评论
     for (ActivityComment comment : commentMap.values()) {
     String parentId = comment.getParentId();
     if (parentId == null || parentId.isEmpty()) {
     rootComments.add(comment);
     } else {
     childrenMap.computeIfAbsent(parentId, k -> new ArrayList<>()).add(comment);
     }
     }
     // 第二次遍历：将子评论添加到父评论中
     for (Map.Entry<String, List<ActivityComment>> entry : childrenMap.entrySet()) {
     String parentId = entry.getKey();
     List<ActivityComment> children = entry.getValue();

     ActivityComment parentComment = findParentComment(parentId, commentMap);
     if (parentComment != null) {
     parentComment.getChildren().addAll(children);
     parentComment.setHasChildren(true);
     } else {
     // 父评论不存在，将子评论作为根评论处理
     rootComments.addAll(children);
     }
     }
     // 递归排序
     sortCommentsRecursively(rootComments);
     return rootComments;
     }

     // 查找父评论的健壮方法
     private ActivityComment findParentComment(String parentId, Map<String, ActivityComment> commentMap) {
     // 1. 直接查找
     ActivityComment parentComment = commentMap.get(parentId);
     if (parentComment != null) {
     return parentComment;
     }

     // 2. 尝试处理ID格式后再次查找
     if (parentId != null) {
     // 尝试去除尾部'0'
     if (parentId.endsWith("0")) {
     String potentialParentId = parentId.substring(0, parentId.length() - 1);
     parentComment = commentMap.get(potentialParentId);
     if (parentComment != null) {
     return parentComment;
     }
     }

     // 3. 尝试遍历匹配（确保键和parentId都清理空格）
     String cleanParentId = parentId.trim();
     for (String key : commentMap.keySet()) {
     String cleanKey = key != null ? key.trim() : "";
     if (!cleanKey.isEmpty() && cleanKey.equals(cleanParentId)) {
     return commentMap.get(key);
     }
     }
     }

     // 未找到父评论
     return null;
     }
     private void asyncUpdateRedisComments(List<ActivityComment> comments) {
     if (comments == null || comments.isEmpty()) {
     return;
     }

     CompletableFuture.runAsync(() -> {
     try {
     // 使用管道批量操作
     redisTemplate.executePipelined((RedisCallback<Object>) connection -> {
     for (ActivityComment comment : comments) {
     // 设置评论数据
     String dataKey = String.format(COMMENT_DATA_KEY, comment.getId());
     byte[] keyBytes = dataKey.getBytes();
     byte[] valueBytes = SerializationUtils.serialize(comment);
     connection.set(keyBytes, valueBytes);

     // 更新文章评论ID列表
     String listKey = String.format(ARTICLE_COMMENTS_KEY, comment.getArticleId());
     connection.zAdd(listKey.getBytes(),
     comment.getCreateTime().toEpochSecond(ZoneOffset.UTC),
     comment.getId().getBytes());
     }
     return null;
     });
     } catch (Exception e) {
     log.error("异步更新Redis评论数据失败", e);
     }
     });
     }
     */

    /**
     * public List<ActivityComment> getCommentsByArticleId(String articleId) {
     * // 构造文章评论的key
     * String listKey = String.format(ARTICLE_COMMENTS_KEY, articleId);
     * // 从Redis中获取评论ID列表（按时间排序，从新到旧）
     * Set<Object> commentIds = redisTemplate.opsForZSet().reverseRange(listKey, 0, -1);
     * if (commentIds == null || commentIds.isEmpty()) {
     * return new ArrayList<>();
     * }
     * // 用于存储所有评论的Map，key为评论ID
     * Map<String, ActivityComment> commentMap = new HashMap<>();
     * // 存储根评论列表
     * List<ActivityComment> rootComments = new ArrayList<>();
     * // 第一次遍历：获取所有评论数据并存入Map
     * for (Object commentId : commentIds) {
     * String dataKey = String.format(COMMENT_DATA_KEY, commentId);
     * ActivityComment comment = (ActivityComment) redisTemplate.opsForValue().get(dataKey);
     * if (comment != null) {
     * comment.setChildren(new ArrayList<>());  // 初始化children列表
     * commentMap.put(comment.getId(), comment);
     * }
     * }
     * // 第二次遍历：构建评论树
     * for (ActivityComment comment : new ArrayList<>(commentMap.values())) {
     * if (comment.getParentId() == null || comment.getParentId().isEmpty()) {
     * // 这是根评论
     * rootComments.add(comment);
     * } else {
     * // 这是子评论
     * ActivityComment parentComment = commentMap.get(comment.getParentId());
     * if (parentComment != null) {
     * parentComment.getChildren().add(comment);
     * // 从commentMap中移除已添加为子评论的评论
     * commentMap.remove(comment.getId());
     * } else {
     * // 如果找不到父评论，作为根评论处理
     * rootComments.add(comment);
     * }
     * }
     * }
     * // 按创建时间排序子评论
     * for (ActivityComment rootComment : rootComments) {
     * if (rootComment.getChildren() != null && !rootComment.getChildren().isEmpty()) {
     * rootComment.getChildren().sort((c1, c2) ->
     * c2.getCreatTime().compareTo(c1.getCreatTime()));
     * }
     * }
     * // 按创建时间排序根评论
     * rootComments.sort((c1, c2) -> c2.getCreatTime().compareTo(c1.getCreatTime()));
     * return rootComments;
     * }
     */
    //生成评论的id
    private String generateUniqueId() {
        return RandomUtil.generateId();
    }

    @Async
    public void saveMessage(ActivityComment comment) {
        String bizId = comment.getId();
        String commentUserId = comment.getUserId();
        UserEntity user = userService.getById(commentUserId);
        String artId = comment.getArticleId();
        ChatMessagesEntity chatMessagesEntity = new ChatMessagesEntity();
        String articleUserId = activityArticleService.getArticleById(artId).getUserId();
//        ActivityArticle activityArticle = activityArticleService.getById(artId);
//        String articleUserId = activityArticle.getUserId();
        if (articleUserId == null) {
            log.error("未找到该帖子的用户");
            return;
        }
        // 获取上级的评论用户信息
        String parentId = comment.getParentId();
        UserEntity parentUser;
        if (!parentId.isEmpty()) {
            ActivityComment parentComment = getById(parentId);
            parentUser = userService.getById(parentComment.getUserId());
        } else {
            ActivityArticle article = activityArticleService.getById(comment.getArticleId());
            parentUser = userService.getById(article.getUserId());
        }
        if (parentUser.getId().equals(commentUserId)) {
            log.error("自己评论自己就不发送消息了");
            return;
        }
        chatMessagesEntity.setBizId(bizId);
        // 评论的不创建会话id了
//        chatMessagesEntity.setConversationId(chatConversationService.getConversation(parentUser.getId(), commentUserId).getId());
        chatMessagesEntity.setPostMessages(comment.getContent());
        chatMessagesEntity.setTime(LocalDateTime.now());
        chatMessagesEntity.setMsgStatus(ChatMessageConstant.MESSAGE_STATUS_UNREAD);
        chatMessagesEntity.setMessagesType(ChatMessageConstant.MESSAGE_TYPE_ACTIVITY_COMMENT);
        chatMessagesEntity.setFormUserId(commentUserId);
        chatMessagesEntity.setToUserId(parentUser.getId());
        chatMessagesService.save(chatMessagesEntity);
        // 发送消息
        // 获取该用户评论的未读数
        int unreadCount = Math.toIntExact(chatMessagesService.count(new QueryWrapper<ChatMessagesEntity>().
                eq("to_user_id", parentUser.getId()).eq("msg_status", ChatMessageConstant.MESSAGE_STATUS_UNREAD)));
        JSONObject resObj = new JSONObject();
        resObj.put("type", "commentMessage");
        resObj.put("user", user);
        resObj.put("unreadCount", unreadCount);
        resObj.put("commentTime", comment.getCreateTime());
        WebSocketChatService.sendMessageToUserId(chatMessagesEntity.getToUserId(), resObj.toJSONString());
        // 发送导航栏红点提醒
        redDotService.sendRedDot(parentUser.getId());
    }
}
